package hero.mps.leet_code_10;

public class Regex {
    static Boolean[][] meno;
    public static boolean isMatch(String s, String p) {
        if (p.isEmpty()) return s.isEmpty();
        boolean firstMatch = (!s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.'));
        if (p.length() >= 2 && p.charAt(1) == '*') {
            return isMatch(s, p.substring(2)) || (firstMatch && isMatch(s.substring(1), p));
        }else {
            return firstMatch && isMatch(s.substring(1), p.substring(1));
        }
    }

    public static boolean isMatch2(String s, String p) {
        boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
        // 初始化dp数组，当s和p都为空字符串时，匹配成功
        dp[0][0] = true;

        // 处理p中以*开头的模式串
        for (int j = 2; j <= p.length(); j++) {
            if (p.charAt(j - 1) == '*') {
                // 如果p当前字符是*，则dp[0][j]取决于dp[0][j-2]
                dp[0][j] = dp[0][j-2];
            }
        }

        // 遍历s中的每个字符
        for (int i = 1; i <= s.length() ; i++) {
            // 遍历p中的每个字符
            for (int j = 1; j <= p.length(); j++) {
                if (p.charAt(j-1) == '*') {
                    // 如果p当前字符是*
                    if (p.charAt(j-2) == s.charAt(i-1) || p.charAt(j-2) == '.') {
                        // 如果p的前一个字符与s当前字符匹配，或者p的前一个字符是.
                        // 则dp[i][j]取决于dp[i][j-2]或dp[i-1][j]
                        dp[i][j] = dp[i][j-2] || dp[i-1][j];
                    }else {
                        // 否则，dp[i][j]只取决于dp[i][j-2]
                        dp[i][j] = dp[i][j-2];
                    }
                }else if (p.charAt(j-1) == s.charAt(i-1) || p.charAt(j-1) == '.') {
                    // 如果p当前字符与s当前字符匹配
                    dp[i][j] = dp[i-1][j-1];
                }
            }
        }

        // 返回最终结果，即s和p是否匹配
        return dp[s.length()][p.length()];

    }

    public static boolean isMatch1(String s, String p) {
        meno = new Boolean[s.length() + 1][ p.length() + 1];
        return dp(0, 0, s, p);
    }

    private static boolean dp(int i, int j, String s, String p) {
        if (meno[i][j] != null) return meno[i][j];
        boolean ans;
        if (j == p.length()) {
            ans = i == s.length();
        }else {
            boolean firstMatch = (i < s.length() && (p.charAt(j) == s.charAt(i) || p.charAt(j) == '.'));
            if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
                ans = dp(i, j+2, s, p) || firstMatch && dp(i+1, j, s, p);
            }else {
                ans = firstMatch && dp(i+1, j + 1, s, p);
            }
        }
        meno[i][j] = ans;
        return ans;
    }

    public static void main(String[] args) {
//        System.out.println(isMatch("aa", "a"));
//        System.out.println(isMatch("aa", ".*"));
//        System.out.println(isMatch("ab", ".*"));
        System.out.println(isMatch2("aab", "c*a*b"));
    }
}
